/*
 * @(#) LTExceptionHandler.java  1.0  2004-2-27
 *
 * Copyright 2003 by LongTop Corporation.
 * 2669 XieTu Road, ShangHai, PRC 200030
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * LongTop Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with LongTop.
 */

package com.cnc.bas;

import com.cnc.bas.util.Constants;
import com.cnc.ssm.UserInfo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.action.*;
import org.apache.struts.config.ExceptionConfig;
import org.apache.struts.util.MessageResources;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;

/**
 * @author Du bf
 * @version 1.0  2005-3-24
 */
public class LTExceptionHandler extends ExceptionHandler {
    private static Log log = LogFactory.getLog(LTExceptionHandler.class);

    public ActionForward execute(java.lang.Exception ex,
                                 ExceptionConfig config,
                                 ActionMapping mapping,
                                 ActionForm formInstance,
                                 javax.servlet.http.HttpServletRequest request,
                                 javax.servlet.http.HttpServletResponse response)
            throws javax.servlet.ServletException {
        ActionForward forward = null;
        ActionError error = null;
        String property = null;
        ActionErrors errors = new ActionErrors();

        /* Get the path for the forward either from the exception element
        * or from the input attribute.
        */
        String path = null;
        path = config.getPath();
        if (path == null)
            path = mapping.getInput();
        if (path == null) {
            if (mapping.findForwards().length > 0)
                forward = mapping.findForward(mapping.findForwards()[0]);
            else
                forward = new ActionForward("failure");
        } else
            forward = new ActionForward(path);
        // Construct the forward object
        /* Figure out what type of exception has been thrown. The Struts
        */
        String messageKey = null;
        Object[] exArgs = null;
        MessageResources mr = ((MessageResources) request.getAttribute(Globals.MESSAGES_KEY));
        Throwable throwable = ex;
        while (throwable != null) {
            exArgs = null;
            messageKey = null;
            if ((ex instanceof LTException)) {
                // This is the specialized behavior
                LTException baseException = (LTException) ex;
                messageKey = baseException.getMessageKey();
                exArgs = baseException.getMessageArgs();
                if (exArgs != null && exArgs.length > 0) {
                    // If there were args provided, use them in the ActionError
                    error = new ActionError(messageKey, exArgs);
                } else {
                    // Create an ActionError without any arguments
                    error = new ActionError(messageKey);
                }
            } else if (ex instanceof LTRuntimeException) {
                LTRuntimeException rex = (LTRuntimeException) ex;
                messageKey = rex.getMessageKey();
                exArgs = rex.getMessageArgs();
                if (exArgs != null && exArgs.length > 0) {
                    // If there were args provided, use them in the ActionError
                    error = new ActionError(messageKey, exArgs);
                } else if (messageKey != null) {
                    // Create an ActionError without any arguments
                    error = new ActionError(messageKey);
                } else
                    error = new ActionError("bas.error.detail", throwable.getMessage());
            } else if (ex instanceof DataAccessException) {
                if (ex instanceof DataIntegrityViolationException) {
                    error = new ActionError("error.database.dataintegrityviolation");
                    property = error.getKey();
                    //messageKey = config.getKey();
                    messageKey = null;
                    exArgs = null;
                } else {
                    error = new ActionError("error.database.general");
                    property = error.getKey();
                    //messageKey = config.getKey();
                    messageKey = null;
                    exArgs = null;
                }

            } else {
                error = new ActionError("bas.error.detail", throwable.getMessage());
                property = error.getKey();
                //messageKey = config.getKey();
                messageKey = null;
                exArgs = null;
            }
            UserInfo oper = (UserInfo) request.getSession().getAttribute(Constants.USER_KEY);
            String userName = null;
            if (oper != null)
                userName = oper.getUserName();
            String url = String.valueOf(request.getRequestURL());

            String ip = request.getRemoteAddr();
            String message = "User code=" + userName + " ; URL=" + url + " ; IP=" + ip + " ; ";
            if (messageKey != null) {
                log.error(message + mr.getMessage(messageKey, exArgs), ex);
            } else {
                log.error(message + throwable.getMessage(), ex);
            }
            errors.add(ActionErrors.GLOBAL_ERROR, error);
            //throwable = throwable.getCause();
            throwable = null;
        }
        // Store the ActionError into the proper scope
        // The storeException method is defined in the parent class
        //storeException(request, name, error, forward, config.getScope());
        if ("request".equals(config.getScope())) {
            request.setAttribute(Globals.ERROR_KEY, errors);
        } else {
            request.getSession().setAttribute(Globals.ERROR_KEY, errors);
        }
        return forward;
    }
}
